package com.yanggu.payment.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yanggu.payment.config.WeiXinPayConfig;
import com.yanggu.payment.entity.OrderInfo;
import com.yanggu.payment.entity.RefundInfo;
import com.yanggu.payment.entity.weixinpay.req.WechatAppPayCloseParams;
import com.yanggu.payment.entity.weixinpay.resp.WechatAppQueryResult;
import com.yanggu.payment.entity.weixinpay.resp.WeiXinPayApplyRefundResp;
import com.yanggu.payment.entity.weixinpay.resp.WeiXinPayRefundNotify;
import com.yanggu.payment.enums.OrderStatus;
import com.yanggu.payment.enums.PayType;
import com.yanggu.payment.enums.wxpay.WxRefundStatus;
import com.yanggu.payment.enums.wxpay.WxTradeState;
import com.yanggu.payment.feign.weixin_pay.WeiXinPayFeign;
import com.yanggu.payment.service.OrderInfoService;
import com.yanggu.payment.service.RefundInfoService;
import com.yanggu.payment.service.WeiXinPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * @version V1.0
 * @author: YangGu
 * @date: 2022/5/7 10:48
 * @description:
 */
@Component
public class WeiXinPayTask {

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private WeiXinPayFeign weiXinPayFeign;

    @Autowired
    private WeiXinPayConfig weiXinPayConfig;

    @Autowired
    private WeiXinPayService weiXinPayService;

    @Autowired
    private RefundInfoService refundInfoService;

    /**
     * 每隔30秒查询5分钟内未使用微信支付的订单
     * 手动调用微信查询订单API, 查询订单是否支付, 如果订单已经支付, 修改商户订单状态为支付成功
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void confirmOrderPayOrNot() {
        //查询所有未支付的订单
        LambdaQueryWrapper<OrderInfo> wrapper = Wrappers.<OrderInfo>lambdaQuery()
                .eq(OrderInfo::getOrderStatus, OrderStatus.NOTPAY.getType())
                .eq(OrderInfo::getPaymentType, PayType.WXPAY.getType())
                .gt(OrderInfo::getCreateTime, DateUtil.offsetMinute(new Date(), -5))
                .isNotNull(OrderInfo::getCodeUrl);
        List<OrderInfo> list = orderInfoService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            return;
        }
        for (OrderInfo orderInfo : list) {
            //调用微信查单API(根据订单号和商户号)
            WechatAppQueryResult wechatAppQueryResult = weiXinPayFeign.queryForOutTradeNo(orderInfo.getOrderNo(), weiXinPayConfig.getMchId());
            String tradeState = wechatAppQueryResult.getTradeState();
            //如果订单支付成功, 处理订单
            if (StrUtil.equals(WxTradeState.SUCCESS.getType(), tradeState)) {
                weiXinPayService.handlerWeiXinPaySuccess(wechatAppQueryResult);
            }
        }
    }

    /**
     * 每隔30s执行关闭超时且未支付的订单
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void closeTimeOutOrder() {
        //查询所有未支付的订单
        LambdaQueryWrapper<OrderInfo> wrapper = Wrappers.<OrderInfo>lambdaQuery()
                .eq(OrderInfo::getOrderStatus, OrderStatus.NOTPAY.getType())
                .eq(OrderInfo::getPaymentType, PayType.WXPAY.getType())
                .le(OrderInfo::getCreateTime, DateUtil.offsetMinute(new Date(), -5))
                .isNotNull(OrderInfo::getCodeUrl);
        List<OrderInfo> list = orderInfoService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            return;
        }
        list.forEach(tempOrder -> {

            //修改订单状态为关闭
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setId(tempOrder.getId());
            orderInfo.setOrderStatus(OrderStatus.CLOSED.getType());
            orderInfoService.updateById(orderInfo);

            //调用微信支付 取消订单API
            WechatAppPayCloseParams params = new WechatAppPayCloseParams();
            params.setMchId(weiXinPayConfig.getMchId());
            weiXinPayFeign.cancelOrder(tempOrder.getOrderNo(), params);
        });
    }

    /**
     * 查询出退款中的订单, 然后手动调用微信查询退款API。
     * 更新订单状态和退款单的状态
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void confirmOrderRefund() {
        LambdaQueryWrapper<RefundInfo> wrapper = Wrappers.<RefundInfo>lambdaQuery()
                .eq(RefundInfo::getRefundStatus, WxRefundStatus.PROCESSING.getType());
        List<RefundInfo> list = refundInfoService.list(wrapper);

        if (CollUtil.isEmpty(list)) {
            return;
        }

        for (RefundInfo refundInfo : list) {
            WeiXinPayApplyRefundResp weiXinPayApplyRefundResp = weiXinPayFeign.queryRefundNo(refundInfo.getRefundNo());
            WeiXinPayRefundNotify weiXinPayRefundNotify = BeanUtil.copyProperties(weiXinPayApplyRefundResp, WeiXinPayRefundNotify.class);
            weiXinPayRefundNotify.setRefundStatus(weiXinPayApplyRefundResp.getStatus());
            weiXinPayService.handlerWeiXinRefundNotify(weiXinPayRefundNotify);
        }
    }

}
